Filtering in various Modules

Hi,

I am new to DXL scripting and I need some help with my first "big" DXL code :)

I'm trying to open a Module -> apply some filters -> write the number of accepted objects in a textfile -> close the module -> open the next module -> ...



This is an example of the code I wrote:

 

Stream outputFile = write "PerformanceIndicators.txt"
 
// declare filter
Filter fCategoryRequirements = (attribute "Category" != "Comment") && (attribute "Category" != "Heading")
Filter fStateReleased = (attribute "State" == "Released")
 
// set filter and return number of accepted objects
void getFilterResults(Module m, Filter f){
    int iAccepted = 0
        int iRejected = 0
        
        set(m, f, iAccepted, iRejected) //<-- *** HERE IS THE PROBLEM ***
 
        outputFile << "|" iAccepted "" //"" converts "int" to "string"
}
 
//Module1
Module m1 = read(fullName itemFromID("00000610"), false) //open module to read
        outputFile << name(m1) " (" uniqueID(m1) ")" //write modulename + ID
 
        outputFile << stringOf(m1, fCategoryRequirements) //output filter
        getFilterResults(m1, fCategoryRequirements)
close(m1)
 
//Module2
Module m2 = read(fullName itemFromID("0000074c"), false) //open module to read
        outputFile << "\n" name(m2) " (" uniqueID(m2) ")" //write modulename + ID
 
        outputFile << "\n" stringOf(m2, fStateReleased) //output filter
        getFilterResults(m2, fCategoryRequirements)
close(m2)



And this is the error I get:



 

 

-R-E- DXL: <Line:12> An unexpected error has occurred: doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 001B:004B31D6



The strange thing is, that the first module (m1) works. If I switch the order and start with the other module (m2) then this module works and the error occurs when the filter in the "m1"- module gets set.

 



I tried for hours, but now I am clueless.
Is there anybody who can help me?

Thanks in anticipation,
Johnny


Johnny_P - Mon Feb 20 10:54:12 EST 2012

Re: Filtering in various Modules
Mathias Mamsch - Mon Feb 20 12:03:18 EST 2012

You need to take care, when declaring the filter. The filters are declared in the scope of a module, however you declare the filters at the start of your script. Make sure you set a current module, then declare the filter. This should resolve the crash problems:

Stream outputFile = write "PerformanceIndicators.txt"
 
// declare filter
 
 
// set filter and return number of accepted objects
void getFilterResults(Module m, Filter f){
    int iAccepted = 0
        int iRejected = 0
        
        set(m, f, iAccepted, iRejected) //<-- *** HERE IS THE PROBLEM ***
 
        outputFile << "|" iAccepted "" //"" converts "int" to "string"
}
 
//Module1
Module m1 = read(fullName itemFromID("00000610"), false) //open module to read
        current = m1; Filter fCategoryRequirements = (attribute "Category" != "Comment") && (attribute "Category" != "Heading")
        outputFile << name(m1) " (" uniqueID(m1) ")" //write modulename + ID
        outputFile << stringOf(m1, fCategoryRequirements) //output filter
        getFilterResults(m1, fCategoryRequirements)
close(m1)
 
//Module2
Module m2 = read(fullName itemFromID("0000074c"), false) //open module to read
        current = m2; Filter fStateReleased = (attribute "State" == "Released")
        outputFile << "\n" name(m2) " (" uniqueID(m2) ")" //write modulename + ID
 
        outputFile << "\n" stringOf(m2, fStateReleased) //output filter
        getFilterResults(m2, fCategoryRequirements)
close(m2)

 


Note: This thread could maybe be interesting for you: https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14535573&#14535573

Hope that helps, regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Filtering in various Modules
llandale - Mon Feb 20 18:34:32 EST 2012

Stream outputFile = write "PerformanceIndicators.txt"

  • That will put your file in the Windows "current directory" which I think for a workstation is your DOORS install directory. Seems to me you should be more specific, perhaps:
  • Stream outputFile = write "c:/Temp/PerformanceIndicators.txt"

Filter fCategoryRequirements = (attribute "Category" != "Comment") && (attribute "Category" != "Heading")

  • If "Category" is a single enumeration (meaning it can be exactly one value, not both "Comment" and "Heading") then this code works, although you probably want to add this, to ignore Objects with no category:
    • && (attribute "Category" != "")
  • If "Category" is multi-enumerated meaning it can have values "Heading" and also "Requirement", then you need this:
    • Filter fCategoryRequirements = !includes(attribute "Category", "Comment") && !includes (attribute "Category" != "Heading") && (attribute "Category" != "")
  • Actually I'd say you should filter positively, if it is a "Requirement" or a "Diagram" or whatever.

After you open a module you should set it current if you use implied "current Module" stuff like Filters as suggested by Mathias:

  • m1 = current

Seems to me you are more likely to know the full name of your desired modules than you are their unique IDs.

  • Module m1 = read("/MyProject/MyFolder/MyModule1", false)

Seems to me that your script is at the mercy of the default view, such as if it excludes levels or does show deleted objects. To resolve this (and to avoid nasty Layouts and to open faster) use the 3rd parameter to "read", open the Standard view so you know the state of the module before you start filtering.

  • Module m1 = read("/MyProject/MyFolder/MyModule1", false, true)

Your Filter isn't going to work when you open the module invisibly "false". Hate it when that happens and you are counting 100 modules; it takes up your monitor and runs drastically slower.

  • Module m1 = read("/MyProject/MyFolder/MyModule1", true, true)

I'm not sure I've ever actually deployed a DXL using a "Filter" and certainly never as a mechanism for counting objects. Perhaps do something like this:

int   CountQualifyingObjects(Module mod)
{   Object obj
    int Count = 0
    string AttrVal
    for obj in entire mod do
    {  if (isDeleted(obj)) continue
       AttrVal = obj."Category"
       if (AttrVal != "Comment" and AttrVal != "Heading") Count++
    }
    return(Count)
}


-Louie

Re: Filtering in various Modules
Johnny_P - Thu Feb 23 03:27:13 EST 2012

Thank you guys for the quick response and sorry mine took so long :)

@Matthias
Declaring the filters after the module (like in your example) does not work for me. I get the same error.

Thank you for the linked thread! This looks interresting and maybe I can use some parts of this idea!

@Louie
  • Stream outputFile = write "PerformanceIndicators.txt"
    • That will put your file in the Windows "current directory" which I think for a workstation is your DOORS install directory. Seems to me you should be more specific, perhaps:
    • Stream outputFile = write "c:/Temp/PerformanceIndicators.txt"

Thanks, I changed that.

  • Filter fCategoryRequirements = (attribute "Category" != "Comment") && (attribute "Category" != "Heading")
    • If "Category" is a single enumeration (meaning it can be exactly one value, not both "Comment" and "Heading") then this code works, although you probably want to add this, to ignore Objects with no category:

There are no Objects with no category in our modules.

  • If "Category" is multi-enumerated meaning it can have values "Heading" and also "Requirement", then you need this:

Category is a single choise attribute.

  • Actually I'd say you should filter positively, if it is a "Requirement" or a "Diagram" or whatever.

We have different kinds of requirements in our modules and I wanted to use the filter for all Modules. So I thougt I exclude all non requirement objects.

  • After you open a module you should set it current if you use implied "current Module" stuff like Filters as suggested by Mathias:
    • m1 = current

Thanks, I added this.

  • Seems to me you are more likely to know the full name of your desired modules than you are their unique IDs.

Yeah, I had it like this the first time, but recently we changed a lot of modulenames, so I thougt using the ID saves me labour in the future.

  • *Seems to me that your script is at the mercy of the default view, such as if it excludes levels or does show deleted objects. To resolve this (and to avoid nasty Layouts and to open faster) use the 3rd parameter to "read", open the Standard view so you know the state of the module before you start filtering.+ Your Filter isn't going to work when you open the module invisibly "false". Hate it when that happens and you are counting 100 modules; it takes up your monitor and runs drastically slower.

I changed these two advices too.

And thank you for your example code. Actually I'm using a mix of my old code and yours now.

Due to heavy time pressure the code is a little mixup and not so clean at the moment. When there is the opportunity I'm going to clean it up and then I think I can post it here ;)
BR, Johnny